package application.windows;

import application.anno.AutoClose;
import application.anno.Layout;
import application.anno.impl.InjectionImpl;
import application.entity.StageEntity;
import application.exception.NotFoundNecessaryAnnotationException;
import application.manager.FloatWindowManager;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.stage.PopupWindow;

import java.io.IOException;

/**
 * 继承此类可以定制悬浮窗口
 * 在此类上方使用Layout注解，来加载PopupWindow的新布局
 * 在此类上使用AutoClose注解，来设置是否自动关闭PopupWindow
 */
public class FloatWindow extends PopupWindow {

    public FloatWindow() {
        super();
    }
    /**
     * 初始化PopupWindow
     *
     * @throws IOException 当注册PopupWindow布局失败时，将会抛出此异常
     */
    public void init() throws IOException, IllegalAccessException {
        // 获取PopupWindow的Layout注解
        Layout annotation = this.getClass().getAnnotation(Layout.class);
        if (annotation == null) {
            // 若找不到Layout注解时，则会抛出此异常。提示缺少必要资源信息。
            throw new NotFoundNecessaryAnnotationException("Not found Layout annotation, can not get layout resource");
        }
        // 获取PopupWindow的资源名称
        String value = annotation.value();
        if (value.isEmpty()) {
            // Layout注解中的信息为空时，则抛出此异常，提示必要信息不能是空的。
            throw new NotFoundNecessaryAnnotationException("Necessary can not empty or null");
        }
        // 获取悬浮窗管理者
        FloatWindowManager floatWindowManager = FloatWindowManager.getInstance();
        // 注册悬浮窗布局，并且获取悬浮窗信息实体类
        StageEntity register = floatWindowManager.register(value);
        // 获取当前悬浮窗的场景对象
        Scene scene = this.getScene();
        // 设置悬浮窗为不透明，背景色为白色
        register.getPane().setStyle("-fx-border-style: solid inside;-fx-border-radius: 5;-fx-border-color: #F2F2F2;-fx-background-color: #FFFFFF");
        // 设置PopupWindow的布局
        scene.setRoot(register.getPane());
        // 获取PopupWindow的AutoClose注解
        AutoClose autoClose = this.getClass().getAnnotation(AutoClose.class);
        if (autoClose != null) {
            // 若AutoClose注解不为空，则设置此窗口的关闭模式。
            this.setAutoHide(autoClose.value());
        }
        // 一下操作，用于在窗口显示前，做一些成员变量的自动注入操作。
        InjectionImpl injection = new InjectionImpl();
        injection.injectionField(this);
    }

    // 显示PopupWindow
    @Override
    public void show(Node ownerNode, double anchorX, double anchorY) {
        if (this.isShowing()) {
            // 若窗口为显示状态，则隐藏掉重新显示
            this.hide();
        }
        super.show(ownerNode, anchorX, anchorY);
    }
}
